/*
 * 路由
 *
 * @Author:    zhoujk
 * @Date:      2022-09-06 20:52:04
 */
import nProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { nextTick } from 'vue'
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import { routerArray } from './routers'
import { PAGE_PATH_404, PAGE_PATH_LOGIN, HOME_PAGE_PATH, PAGE_PATH_WHITELIST } from '/@/constants/common-const'
import { HOME_PAGE_NAME } from '/@/constants/system/home-const'
import SmartLayout from '../layout/index.vue'
import { useUserStore } from '/@/store/modules/system/user'
import { localClear, localRead } from '/@/utils/local-util'
import _ from 'lodash'
import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js'

export const router = createRouter({
  history: createWebHistory(),
  routes: routerArray,
  strict: true,
  scrollBehavior: () => ({ left: 0, top: 0 }),
})

// ----------------------- 路由加载前 -----------------------
router.beforeEach(async (to, from, next) => {
  // 进度条开启
  nProgress.start()

  // 公共页面，任何时候都可以跳转
  if (to.path === PAGE_PATH_404) {
    next()
    return
  }

  // 公共页面，任何时候都可以跳转
  if (PAGE_PATH_WHITELIST.includes(to.path)) {
    next()
    return
  }

  // 验证登录
  const token = localRead(LocalStorageKeyConst.USER_TOKEN)
  if (!token) {
    useUserStore().logout()
    if (to.path === PAGE_PATH_LOGIN) {
      next()
    } else {
      next({ path: PAGE_PATH_LOGIN })
    }
    return
  }

  // 登录页，则跳转到首页
  if (to.path === PAGE_PATH_LOGIN) {
    next({ path: HOME_PAGE_PATH })
    return
  }

  // 首页（ 需要登录 ，但不需要验证权限）
  if (to.path === HOME_PAGE_NAME) {
    next()
    return
  }

  // 下载路由对应的 页面组件，并修改组件的Name，如果修改过，则不需要修改
  let toRouterInfo = routerMap.get(to.name)
  if (toRouterInfo && _.isFunction(toRouterInfo.component) && toRouterInfo.meta.renameComponentFlag === false) {
    // 因为组件component 为 lazy load是个方法，所以可以直接执行 component()方法
    toRouterInfo.component().then((val) => {
      // 修改组件的name
      val.default.name = to.meta.componentName
      // 记录已经修改过 组件的name
      toRouterInfo.meta.renameComponentFlag = true
    })
  }

  // 设置tagNav
  useUserStore().setTagNav(to, from)

  // 设置keepAlive
  if (to.meta.keepAlive) {
    nextTick(() => {
      useUserStore().pushKeepAliveIncludes(to.meta.componentName)
    })
  }

  next()
})

// ----------------------- 路由加载后 -----------------------
router.afterEach(() => {
  nProgress.done()
})

// ----------------------- 构建router对象 -----------------------
const routerMap = new Map()

export function buildRoutes(menuRouterList) {
  let menuList = menuRouterList ? menuRouterList : useUserStore().getMenuRouterList || []
  /**
   * 1、构建整个路由信息
   * 2、添加到路由里
   */
  const routerList = []
  // 获取所有vue组件引用地址 用于构建路由
  const modules = import.meta.glob('../views/**/**.vue')
  // 获取所有vue组件 用于注入name属性 name属性用于keep-alive

  //1、构建整个路由信息
  for (const e of menuList) {
    if (!e.id) {
      continue
    }
    if (!e.path) {
      continue
    }
    if (e.status && e.status === 0) {
      continue
    }
    let route = {
      path: e.path.startsWith('/') ? e.path : `/${e.path}`,
      // 使用【id】作为name唯一标识
      name: e.id.toString(),
      meta: {
        // 数据库菜单(页面)id
        id: e.id.toString(),
        // 组件名称
        componentName: e.id.toString(),
        // 菜单展示
        title: e.name,
        // 菜单图标展示
        icon: e.icon,
        // 是否在菜单隐藏
        hideInMenu: false,
        // 页面是否keep-alive缓存
        keepAlive: false,
        // 是否为外链
        frameFlag: false,
        // 外链地址
        frameUrl: null,
        // 是否 rename了组件的名字
        renameComponentFlag: false,
      },
    }

    if (e.frameFlag) {
      route.component = () => import('../components/framework/iframe/iframe-index.vue')
    } else {
      let componentPath = e.component && e.component.startsWith('/') ? e.component : '/' + e.component
      let relativePath = `../views${componentPath}`
      // // eslint-disable-next-line no-prototype-builtins
      route.component = modules[relativePath]
    }

    routerList.push(route)
    routerMap.set(e.id.toString(), route)
  }

  //2、添加到路由里
  router.addRoute({
    path: '/',
    meta: {},
    component: SmartLayout,
    children: routerList,
  })
}
